package com.qinggeng.project.system.controller;

import com.qinggeng.common.enums.*;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.common.utils.SecurityUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.common.utils.poi.ExcelUtil;
import com.qinggeng.framework.aspectj.lang.annotation.Log;
import com.qinggeng.framework.aspectj.lang.enums.BusinessType;
import com.qinggeng.framework.config.mq.MQSendUtils;
import com.qinggeng.framework.config.mq.dto.MessageOrdersMessageDTO;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.framework.redis.RedisLock;
import com.qinggeng.framework.web.controller.BaseController;
import com.qinggeng.framework.web.domain.AjaxResult;
import com.qinggeng.framework.web.page.TableDataInfo;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.domain.vo.OrderLineVo;
import com.qinggeng.project.system.domain.vo.OrderStatifyVo;
import com.qinggeng.project.system.domain.vo.OrderStatisticsVO;
import com.qinggeng.project.system.dto.OrderStatisticsDTO;
import com.qinggeng.project.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 订单列Controller
 *
 * @author qinggeng
 * @date 2020-06-17
 */
@RestController
@RequestMapping("/system/orders")
public class OrdersController extends BaseController {
    @Autowired
    private IOrdersService ordersService;

    @Autowired
    private IUserMessageService userMessageService;

    @Autowired
    private IUserAliasService userAliasService;

    @Autowired
    private IOrdersReturnService ordersReturnService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${token.secret}")
    private String secret;

    @Autowired
    private IShopService shopService;

    @Autowired
    private MQSendUtils mqSendUtils;

    @Autowired
    private MQSendService mqSendService;
    @Autowired
    private IOrdersGiftService ordersGiftService;
    /**
     * 查询订单列列表
     */
    @PreAuthorize("@ss.hasPermi('system:orders:list')")
    @GetMapping("/list")
    public TableDataInfo list(Orders orders) {
        startPage();
        if (SecurityUtils.getLoginUser().getUser().getUserType().equals(UserTypeEnum.SHOP.getCode())){
            orders.setShopId(SecurityUtils.getShopId());
        }
        orders.setDelFlag("0");
        List<Orders> list = ordersService.selectOrdersList(orders);
        return getDataTable(list);
    }


    /**
     * 查询订单列列表
     */
    @PreAuthorize("@ss.hasPermi('system:orders:list')")
    @GetMapping("/listByTime")
    public TableDataInfo listByTime(Orders orders) {

        if (SecurityUtils.getLoginUser().getUser().getUserType().equals(UserTypeEnum.SHOP.getCode())){
            orders.setShopId(SecurityUtils.getShopId());
        }
        orders.setDelFlag("0");
        List<Orders> list = ordersService.listOrdersByTime(orders);
        return getDataTable(list);
    }

    /**
     * 查询退款订单列表
     */
    @PreAuthorize("@ss.hasPermi('system:orders:list')")
    @GetMapping("/refundList")
    public TableDataInfo refundList(Orders orders) {
        startPage();
        if (SecurityUtils.getLoginUser().getUser().getUserType().equals(UserTypeEnum.SHOP.getCode())){
            orders.setShopId(SecurityUtils.getShopId());
        }

        OrdersReturn ordersReturn = new OrdersReturn();
        if (!StringUtils.isEmpty(orders.getOrdersNo())){
            ordersReturn.setOrdersNo(orders.getOrdersNo());
        }

        List<OrdersReturn> list = ordersReturnService.selectOrdersReturnList(ordersReturn);
        return getDataTable(list);
    }

    /**
     * 退款
     */
    @PreAuthorize("@ss.hasPermi('system:orders:edit')")
    @GetMapping("/refund/{ordersReturnId}/{payment}")
    public AjaxResult refund(@PathVariable("ordersReturnId") Long ordersReturnId,@PathVariable("payment") BigDecimal payment) {
        //redis锁防止表单重复提交
        RedisLock redisLock = new RedisLock(redisTemplate, "ORDERS_RETURN_ID" + ordersReturnId);
        try {
            if (!redisLock.lockNoRetry()) {
                return AjaxResult.error("服务繁忙");
            }
            ordersReturnService.confirmReturn(ordersReturnId,payment);
            return AjaxResult.success("退款成功");
        } catch (CustomException e) {
            return AjaxResult.error(e.getMessage());
        } finally {
            redisLock.unlock();
        }
    }

    @PreAuthorize("@ss.hasPermi('system:orders:remove')")
    @DeleteMapping("/refund/{ordersReturnIds}")
    public AjaxResult delRefund(@PathVariable("ordersReturnIds") Long[] ordersReturnIds) {
        return toAjax(ordersReturnService.deleteOrdersRetrunByIds(ordersReturnIds));
    }



    /**
     * 导出订单列列表
     */
    @PreAuthorize("@ss.hasPermi('system:orders:export')")
    @Log(title = "订单列", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(Orders orders) {
        if (SecurityUtils.getLoginUser().getUser().getUserType().equals(UserTypeEnum.SHOP.getCode())){
            orders.setShopId(SecurityUtils.getShopId());
        }
        List<Orders> list = ordersService.selectOrdersList(orders);
        ExcelUtil<Orders> util = new ExcelUtil<Orders>(Orders.class);
        return util.exportExcel(list, "orders");
    }


    /**
     * 获取订单列详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:orders:query')")
    @GetMapping(value = "/{ordersId}")
    public AjaxResult getInfo(@PathVariable("ordersId") Long ordersId) {
        Orders orders=ordersService.selectOrdersById(ordersId);
        orders.setGiftList(ordersGiftService.selectOrdersGiftListByOrdersId(ordersId));
        return AjaxResult.success(orders);
    }

    /**
     * 新增订单列
     */
    @PreAuthorize("@ss.hasPermi('system:orders:add')")
    @Log(title = "添加", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Orders orders) {
        return toAjax(ordersService.insertOrders(orders));
    }

    /**
     * 修改订单列
     */
    @PreAuthorize("@ss.hasPermi('system:orders:edit')")
    @Log(title = "编辑", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Orders orders) {
        return toAjax(ordersService.updateOrdersState(orders));
    }

    /**
     * 删除订单列
     */
    @PreAuthorize("@ss.hasPermi('system:orders:remove')")
    @Log(title = "订单列", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ordersIds}")
    public AjaxResult remove(@PathVariable Long[] ordersIds) {
        return toAjax(ordersService.deleteOrdersByIds(ordersIds));
    }

    /**
     * 统计订单数据用于首页展示
     *
     * @return
     */
    @GetMapping("/statifyOrderCount")
    public AjaxResult statifyOrderCount() {
        //统计全部
        OrderStatifyVo orderStatifyVo = ordersService.statifyOrderCountAll();
        //统计当天
        OrderStatifyVo orderStatifyToday = ordersService.orderStatifyToday();
        orderStatifyVo.setTodayCount(orderStatifyToday.getTodayCount());
        orderStatifyVo.setTodayMoney(orderStatifyToday.getTodayMoney());
        return AjaxResult.success(orderStatifyVo);
    }

    @GetMapping("/statifyOrderLine")
    public AjaxResult statifyOrderLine() {
        List<OrderLineVo> orderLineVoList = ordersService.statifyOrderLine();
        if (orderLineVoList.size() > 0) {
            //统计时间
            List<String> dataArr = new ArrayList<>();
            //统计个数
            List<Integer> countArr = new ArrayList<>();
            //统计金钱
            List<BigDecimal> moneyArr = new ArrayList<>();
            for (OrderLineVo orderLineVo : orderLineVoList) {
                dataArr.add(orderLineVo.getDays());
                countArr.add(orderLineVo.getOrderCount());
                moneyArr.add(orderLineVo.getAllMoney());
            }
            Map map = new LinkedHashMap();
            map.put("days", dataArr.toArray(new String[]{}));
            map.put("expectedData", countArr.toArray(new Integer[]{}));
            map.put("actualData", moneyArr.toArray(new BigDecimal[]{}));
            return AjaxResult.success(map);
        }else{
            return AjaxResult.error("暂无数据");
        }
    }

    /**
     * 订单发货
     * @param ordersNo
     * @return
     */
    @GetMapping("/ship/{ordersNo}")
    public AjaxResult ship(@PathVariable("ordersNo") String ordersNo){
        ordersService.ordersShip(ordersNo);
        return AjaxResult.success("发货成功");
    }

    /**
     * 修改订单打印状态为20=已打印
     * @param ordersId
     * @return
     */
    @GetMapping("/print")
    public AjaxResult print(String secret,Long ordersId){
        if(StringUtils.isEmpty(secret)||!secret.equals(this.secret)){
            return AjaxResult.error("令牌秘钥不正确");
        }
        Orders orders=ordersService.selectOrdersById(ordersId);
        if(orders==null){
            return AjaxResult.error("订单不存在");
        }
        if(!orders.getPrintStatus().equals(CommonEnum.STATUS_10.getValue())){
            return AjaxResult.error("订单不可打印！");
        }
        try{
            boolean result=ordersService.updateOrdersPrintStatus(orders,"10","20");
            if(!result){
                logger.error("打印失败，请重试！");
                throw new CustomException("打印失败，请重试！");
            }
            return AjaxResult.success("打印成功！");
        }catch (Exception e){
            logger.error("打印失败，请重试！{}",e.getMessage());
            throw new CustomException("打印失败，请重试！");
        }
    }

    /**
     * 已打印过的订单修改打印状态为10=未打印
     * @param ordersId
     * @return
     */
    @GetMapping("/reprint/{ordersId}")
    public AjaxResult reprint(@PathVariable("ordersId") Long ordersId){
        Orders orders=ordersService.selectOrdersById(ordersId);
        if(orders==null){
            return AjaxResult.error("订单不存在",ShowTypeEnum.用户.getValue());
        }
        if(!orders.getPrintStatus().equals(PrintStatusEnum.已打印.getStatus())){
            return AjaxResult.error("订单尚未打印过！",ShowTypeEnum.用户.getValue());
        }
        boolean result=ordersService.updateOrdersPrintStatus(orders,"20","10");
        if(!result){
            return AjaxResult.error("打印失败，请重试！",ShowTypeEnum.用户.getValue());
        }
        return AjaxResult.success("重新打印成功！",ShowTypeEnum.用户.getValue());
    }

    /**
     * 获取订单打印数据
     * @param shopId
     * @return
     */
    @GetMapping("/printData")
    public AjaxResult getOrdersPrintDataList(String secret,Long shopId){
        if(StringUtils.isEmpty(secret)||!secret.equals(this.secret)){
            return AjaxResult.error("令牌秘钥不正确");
        }
        if(shopId==null){
            return AjaxResult.error("商铺ID不能为空！");
        }
        Shop shop=shopService.selectShopById(shopId);
        if(shop==null){
            return AjaxResult.error("商铺不存在！");
        }
        return AjaxResult.success(ordersService.selectPrintDataList(shopId));
    }

    @GetMapping("/printStatus")
    public AjaxResult printStatus(String secret,Long ordersId){
        if(StringUtils.isEmpty(secret)||!secret.equals(this.secret)){
            return AjaxResult.error("令牌秘钥不正确");
        }
        if(ordersId==null){
            return AjaxResult.error("订单ID不能为空！");
        }
        Orders orders=ordersService.selectOrdersById(ordersId);
        if(orders==null){
            return AjaxResult.error("订单存在！");
        }
        return AjaxResult.success("查询成功！",ordersService.getOrdersPrintStatus(orders));
    }
    @GetMapping("/orderStatistics")
    public AjaxResult orderStatistics(OrderStatisticsDTO dto){
        List<OrderStatisticsVO> orderStatisticsVOS=ordersService.listOrderStatistics(dto);
        return AjaxResult.success(orderStatisticsVOS);
    }
}
